#pragma once
#include "DataDef.h"
#include "DeviceHolder.h"
#include <vector>

using namespace std;

#define MGR_GET_TEX(key, mgr) (mgr->getTexture(key))
#define MGR_GET_SUF(key, mgr) (mgr->getSurface(key))

typedef struct 
{
	LPDIRECT3DTEXTURE9 texture;
	LPCWSTR alias;
	bool released;
	bool isRTarget;
} MTexture;

typedef struct 
{
	LPDIRECT3DSURFACE9 surface;
	LPCWSTR alias;
	bool released;
} MSurface;

class TextureManager:
	public DeviceHolder
{
public:

	static int TEXTURE_SIZE;
	static int SHADOW_MAP_SIZE;
	static bool SUPPORT_MRT;

	static D3DFORMAT RT_FORMAT;
	static D3DFORMAT DEPTH_RT_FORMAT;

	TextureManager(LPDIRECT3DDEVICE9 device);
	~TextureManager(void);

	LPDIRECT3DTEXTURE9 makeTexture (
		const LPCWSTR alias, 
		const D3DFORMAT format,
		const UINT width = TEXTURE_SIZE,
		const UINT height = TEXTURE_SIZE);

	LPDIRECT3DSURFACE9 makeSurface (
		const LPCWSTR alias, 
		const D3DFORMAT format,
		const UINT width = TEXTURE_SIZE,
		const UINT height = TEXTURE_SIZE);

	void makeRenderTarget (
		const LPCWSTR alias,
		const D3DFORMAT format,
		const UINT width = TEXTURE_SIZE,
		const UINT height = TEXTURE_SIZE);

	LPDIRECT3DTEXTURE9 loadTexture (const LPCWSTR fileName, const LPCWSTR alias = NULL);

	LPDIRECT3DTEXTURE9 getTexture(const LPCWSTR alias);

	LPDIRECT3DSURFACE9 *getSurface(const LPCWSTR alias);



private:

	MTexture *getMTexture(const LPCWSTR alias);

	MSurface *getMSurface(const LPCWSTR alias);

	void addTexture(const LPDIRECT3DTEXTURE9 texture, const LPCWSTR alias, const bool isRT = false);

	void addSurface(const LPDIRECT3DSURFACE9 surface, const LPCWSTR alias);

	// All the textures.
	vector<MTexture> textures;
	// All the surfaces.
	vector<MSurface> surfaces;
};
